module klang.目标.目标_;
import 全局;
import klang.编译.triple.Triple: Triple, isLittleEndian, isOSBinFormatMachO, isArch32Bit, isAMDGCN, isOSWindows, isOSNaCl, getEnvironment, EnvironmentType, OSType, ARM_parseArch, ARM_ArchKind, ARM_getSubArch, parseArchProfile, ARM_ProfileKind, isWatchABI, isOSNetBSD, isOSOpenBSD, ArchType, isMIPS32, isOSAIX, isOSLinux, isOSBinFormatCOFF, isX32, isOSDarwin, isOSBinFormatWasm, SubArchType, VendorType;
class TargetOptions {
    bool NVPTXUseShortPointers = false;
    this() { }
}
class TargetInfo {
    TargetOptions TargetOpts;
    Triple triple;
    dstring DataLayoutString;
    dstring UserLabelPrefix;
    bool BigEndian;
    this() { }
    this(Triple T) {
        this.triple = T;
        this.TargetOpts = new TargetOptions();
        this.BigEndian = !isLittleEndian(T);
    }
    void resetDataLayout(dstring DL, dstring UserLabelPrefix = ""d) {
        this.DataLayoutString = DL;
        this.UserLabelPrefix = UserLabelPrefix;
    }
    void setDataLayout() { }
}
class OSTargetInfo(T) : T {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class CloudABITargetInfo(T) : OSTargetInfo!(T) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class AnanasTargetInfo(T) : OSTargetInfo!(T) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class DarwinTargetInfo(T) : OSTargetInfo!(T) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class DragonFlyBSDTargetInfo(T) : OSTargetInfo!(T) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class FreeBSDTargetInfo(T) : OSTargetInfo!(T) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class KFreeBSDTargetInfo(T) : OSTargetInfo!(T) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class HaikuTargetInfo(T) : OSTargetInfo!(T) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class HurdTargetInfo(T) : OSTargetInfo!(T) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class MinixTargetInfo(T) : OSTargetInfo!(T) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class LinuxTargetInfo(T) : OSTargetInfo!(T) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class NetBSDTargetInfo(T) : OSTargetInfo!(T) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class OpenBSDTargetInfo(T) : OSTargetInfo!(T) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class PSPTargetInfo(T) : OSTargetInfo!(T) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class PS3PPUTargetInfo(T) : OSTargetInfo!(T) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class PS4OSTargetInfo(T) : OSTargetInfo!(T) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class RTEMSTargetInfo(T) : OSTargetInfo!(T) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class SolarisTargetInfo(T) : OSTargetInfo!(T) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class AIXTargetInfo(T) : OSTargetInfo!(T) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class ZOSTargetInfo(T) : OSTargetInfo!(T) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class WindowsTargetInfo(T) : OSTargetInfo!(T) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class NaClTargetInfo(T) : OSTargetInfo!(T) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class FuchsiaTargetInfo(T) : OSTargetInfo!(T) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class WebAssemblyOSTargetInfo(T) : OSTargetInfo!(T) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class WASITargetInfo(T) : WebAssemblyOSTargetInfo!(T) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class EmscriptenTargetInfo(T) : WebAssemblyOSTargetInfo!(T) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
// AArch64
class AArch64TargetInfo : TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class AArch64leTargetInfo : AArch64TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
    }
    override void setDataLayout() {
        if (isOSBinFormatMachO(this.triple)) {
            if (isArch32Bit(this.triple)) {
                this.resetDataLayout("e-m:o-p:32:32-i64:64-i128:128-n32:64-S128"d, "_"d);
            }
            else {
                this.resetDataLayout("e-m:o-i64:64-i128:128-n32:64-S128"d, "_"d);
            }
        }
        else {
            this.resetDataLayout("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"d);
        }
    }
}
class WindowsARM64TargetInfo : WindowsTargetInfo!(AArch64leTargetInfo) {
    this() { }
    this(Triple T) {
        super(T);
    }
    override void setDataLayout() {
        if (isOSBinFormatMachO(this.triple)) {
            this.resetDataLayout("e-m:o-i64:64-i128:128-n32:64-S128"d, "_"d);
        }
        else {
            this.resetDataLayout("e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128"d);
        }
    }
}
class MicrosoftARM64TargetInfo : WindowsARM64TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class MinGWARM64TargetInfo : WindowsARM64TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class AArch64beTargetInfo : AArch64TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
    }
    override void setDataLayout() {
        this.resetDataLayout("E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"d);
    }
}
class DarwinAArch64TargetInfo : DarwinTargetInfo!(AArch64leTargetInfo) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class RenderScript64TargetInfo : AArch64leTargetInfo {
    this() { }
    this(Triple T) {
        super(T);
    }
    override void setDataLayout() { }
}
// AMDGPU
class AMDGPUTargetInfo : TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
        dstring DataLayoutStringR600 = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1"d;
        dstring DataLayoutStringAMDGCN = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7"d;
        this.resetDataLayout(isAMDGCN(this.triple) ? DataLayoutStringAMDGCN : DataLayoutStringAMDGCN);
    }
}
class ARCTargetInfo : TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
        this.resetDataLayout("e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-f32:32:32-i64:32-f64:32-a:0:32-n32"d);
    }
}
class ARMTargetInfo : TargetInfo {
    dstring ABI;
    this() { }
    this(Triple T) {
        super(T);
        ARM_ArchKind ArchKind;
        dstring ArchName = T.getArchName();
        ARM_ArchKind AK = ARM_parseArch(ArchName);
        if (AK != ARM_ArchKind.INVALID) {
            ArchKind = AK;
        }
        dstring SubArch = ARM_getSubArch(ArchKind);
        ARM_ProfileKind ArchProfile = parseArchProfile(SubArch);
        this.ABI = ""d;
        if (isOSBinFormatMachO(this.triple)) {
            if (getEnvironment(this.triple) == EnvironmentType.EABI || this.triple.OS == OSType.UnknownOS || ArchProfile == ARM_ProfileKind.M) {
                this.setABI("aapcs"d);
            }
            else if (isWatchABI(this.triple)) {
                this.setABI("aapcs16"d);
            }
            else {
                this.setABI("apcs-gnu"d);
            }
        }
        else if (isOSWindows(this.triple)) {
            this.setABI("aapcs"d);
        }
        else {
            switch (getEnvironment(this.triple)) {
                case EnvironmentType.Android:
                case EnvironmentType.GNUEABI:
                case EnvironmentType.GNUEABIHF:
                case EnvironmentType.MuslEABI:
                case EnvironmentType.MuslEABIHF: {
                    this.setABI("aapcs-linux"d);
                    break;
                }
                case EnvironmentType.EABIHF:
                case EnvironmentType.EABI: {
                    this.setABI("aapcs"d);
                    break;
                }
                case EnvironmentType.GNU: {
                    this.setABI("apcs-gnu"d);
                    break;
                }
                default: {
                    if (isOSNetBSD(this.triple)) {
                        this.setABI("apcs-gnu"d);
                    }
                    else if (isOSOpenBSD(this.triple)) {
                        this.setABI("aapcs-linux"d);
                    }
                    else {
                        this.setABI("aapcs"d);
                    }
                    break;
                }
            }
        }
    }
    bool setABI(dstring Name) {
        this.ABI = Name;
        if (Name == "apcs-gnu"d || Name == "aapcs16"d) {
            this.setABIAPCS(Name == "aapcs16"d);
            return true;
        }
        if (Name == "aapcs"d || Name == "aapcs-vfp"d || Name == "aapcs-linux"d) {
            this.setABIAPCS();
            return true;
        }
        return false;
    }
    void setABIAPCS() {
        if (isOSBinFormatMachO(this.triple)) {
            if (this.BigEndian) {
                this.resetDataLayout("E-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"d);
            }
            else {
                this.resetDataLayout("e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"d, "_"d);
            }
        }
        else if (isOSWindows(this.triple)) {
            this.resetDataLayout("e-m:w-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"d);
        }
        else if (isOSNaCl(this.triple)) {
            this.resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S128"d);
        }
        else {
            if (this.BigEndian) {
                this.resetDataLayout("E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"d);
            }
            else {
                this.resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"d);
            }
        }
    }
    void setABIAPCS(bool IsAAPCS16) {
        if (isOSBinFormatMachO(this.triple) && IsAAPCS16) {
            this.resetDataLayout("e-m:o-p:32:32-Fi8-i64:64-a:0:32-n32-S128"d, "_"d);
        }
        else if (isOSBinFormatMachO(this.triple)) {
            if (this.BigEndian) {
                this.resetDataLayout("E-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"d);
            }
            else {
                this.resetDataLayout("e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"d, "_"d);
            }
        }
        else {
            if (this.BigEndian) {
                this.resetDataLayout("E-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"d);
            }
            else {
                this.resetDataLayout("e-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"d);
            }
        }
    }
}
class ARMleTargetInfo : ARMTargetInfo {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class ARMbeTargetInfo : ARMTargetInfo {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class WindowsARMTargetInfo : WindowsTargetInfo!(ARMleTargetInfo) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class ItaniumWindowsARMleTargetInfo : WindowsARMTargetInfo {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class MicrosoftARMleTargetInfo : WindowsARMTargetInfo {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class MinGWARMTargetInfo : WindowsARMTargetInfo {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class CygwinARMTargetInfo : ARMleTargetInfo {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class DarwinARMTargetInfo : DarwinTargetInfo!(ARMleTargetInfo) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class RenderScript32TargetInfo : ARMleTargetInfo {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class AVRTargetInfo : TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
        this.resetDataLayout("e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8"d);
    }
}
class BPFTargetInfo : TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
        if (T.Arch == ArchType.bpfeb) {
            this.resetDataLayout("E-m:e-p:64:64-i64:64-i128:128-n32:64-S128"d);
        }
        else {
            this.resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"d);
        }
    }
}
class HexagonTargetInfo : TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
        this.resetDataLayout("e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048"d);
    }
}
class LanaiTargetInfo : TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
        this.resetDataLayout("E-m:e-p:32:32-i64:64-a:0:32-n32-S64"d);
    }
}
class Le64TargetInfo : TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
        this.resetDataLayout("e-m:e-v128:32-v16:16-v32:32-v96:32-n8:16:32:64-S128"d);
    }
}
class M68kTargetInfo : TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
        dstring Layout = ""d;
        // M68k is Big Endian
        Layout ~= "E"d;
        // FIXME how to wire it with the used object format?
        Layout ~= "-m:e"d;
        // M68k pointers are always 32 bit wide even for 16 bit cpus
        Layout ~= "-p:32:32"d;
        // M68k integer data types
        Layout ~= "-i8:8:8-i16:16:16-i32:16:32"d;
        // FIXME no floats at the moment
        // The registers can hold 8, 16, 32 bits
        Layout ~= "-n8:16:32"d;
        // 16 bit alignment for both stack and aggregate
        // in order to conform to ABI used by GCC
        Layout ~= "-a:0:16-S16"d;
        this.resetDataLayout(Layout);
    }
}
class MipsTargetInfo : TargetInfo {
    dstring ABI;
    this() { }
    this(Triple T) {
        super(T);
        if (isMIPS32(T)) {
            this.ABI = "o32"d;
        }
        else if (getEnvironment(T) == EnvironmentType.GNUABIN32) {
            this.ABI = "n32"d;
        }
        else {
            this.ABI = "n64"d;
        }
        dstring Layout = ""d;
        if (this.ABI == "o32"d) {
            Layout = "m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64"d;
        }
        if (this.ABI == "n32"d) {
            Layout = "m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128"d;
        }
        if (this.ABI == "n64"d) {
            Layout = "m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128"d;
        }
        if (this.BigEndian) {
            this.resetDataLayout("E-"d ~ Layout);
        }
        else {
            this.resetDataLayout("e-"d ~ Layout);
        }
    }
}
class MSP430TargetInfo : TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
        this.resetDataLayout("e-m:e-p:16:16-i32:16-i64:16-f32:16-f64:16-a:8-n8:16-S16"d);
    }
}
class NVPTXTargetInfo : TargetInfo {
    this() { }
    this(Triple T, uint TargetPointerWidth, TargetOptions Opts = ··null!(TargetOptions)) {
        super(T);
        if (Opts !is ··null!(TargetOptions)) {
            this.TargetOpts = Opts;
        }
        if (TargetPointerWidth == 32) {
            this.resetDataLayout("e-p:32:32-i64:64-i128:128-v16:16-v32:32-n16:32:64"d);
        }
        else if ((Opts !is ··null!(TargetOptions)) && Opts.NVPTXUseShortPointers) {
            this.resetDataLayout("e-p3:32:32-p4:32:32-p5:32:32-i64:64-i128:128-v16:16-v32:32-n16:32:64"d);
        }
        else {
            this.resetDataLayout("e-i64:64-i128:128-v16:16-v32:32-n16:32:64"d);
        }
    }
}
class PNaClTargetInfo : TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class NaClMips32TargetInfo : MipsTargetInfo {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class PPCTargetInfo : TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class PPC32TargetInfo : PPCTargetInfo {
    this() { }
    this(Triple T) {
        super(T);
        if (isOSAIX(T)) {
            this.resetDataLayout("E-m:a-p:32:32-i64:64-n32"d);
        }
        else if (T.Arch == ArchType.ppcle) {
            this.resetDataLayout("e-m:e-p:32:32-i64:64-n32"d);
        }
        else {
            this.resetDataLayout("E-m:e-p:32:32-i64:64-n32"d);
        }
    }
}
class PPC64TargetInfo : PPCTargetInfo {
    this() { }
    this(Triple T) {
        super(T);
        dstring DataLayout = ""d;
        if (isOSAIX(T)) {
            DataLayout = "E-m:a-i64:64-n32:64"d;
        }
        else if (T.Arch == ArchType.ppc64le) {
            DataLayout = "e-m:e-i64:64-n32:64"d;
        }
        else {
            DataLayout = "E-m:e-i64:64-n32:64"d;
        }
        if (isOSAIX(T) || isOSLinux(T)) {
            DataLayout ~= "-S128-v256:256:256-v512:512:512"d;
        }
        this.resetDataLayout(DataLayout);
    }
}
class DarwinPPC32TargetInfo : DarwinTargetInfo!(PPC32TargetInfo) {
    this() { }
    this(Triple T) {
        super(T);
        this.resetDataLayout("E-m:o-p:32:32-f64:32:64-n32"d, "_"d);
    }
}
class DarwinPPC64TargetInfo : DarwinTargetInfo!(PPC64TargetInfo) {
    this() { }
    this(Triple T) {
        super(T);
        this.resetDataLayout("E-m:o-i64:64-n32:64"d, "_"d);
    }
}
class AIXPPC32TargetInfo : AIXTargetInfo!(PPC32TargetInfo) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class AIXPPC64TargetInfo : AIXTargetInfo!(PPC64TargetInfo) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class RISCVTargetInfo : TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class RISCV32TargetInfo : RISCVTargetInfo {
    this() { }
    this(Triple T) {
        super(T);
        this.resetDataLayout("e-m:e-p:32:32-i64:64-n32-S128"d);
    }
}
class RISCV64TargetInfo : RISCVTargetInfo {
    this() { }
    this(Triple T) {
        super(T);
        this.resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n64-S128"d);
    }
}
class SparcTargetInfo : TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class SparcV8TargetInfo : SparcTargetInfo {
    this() { }
    this(Triple T) {
        super(T);
        this.resetDataLayout("E-m:e-p:32:32-i64:64-f128:64-n32-S64"d);
    }
}
class SparcV8elTargetInfo : SparcV8TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
        this.resetDataLayout("e-m:e-p:32:32-i64:64-f128:64-n32-S64"d);
    }
}
class SparcV9TargetInfo : SparcTargetInfo {
    this() { }
    this(Triple T) {
        super(T);
        this.resetDataLayout("E-m:e-i64:64-n32:64-S128"d);
    }
}
class SPIRTargetInfo : TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class SPIR32TargetInfo : SPIRTargetInfo {
    this() { }
    this(Triple T) {
        super(T);
        this.resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"d);
    }
}
class SPIR64TargetInfo : SPIRTargetInfo {
    this() { }
    this(Triple T) {
        super(T);
        this.resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"d);
    }
}
class SystemZTargetInfo : TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
        this.resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64"d);
    }
}
class TCETargetInfo : TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
        this.resetDataLayout("E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:32-v128:32:32-v256:32:32-v512:32:32-v1024:32:32-a0:0:32-n32"d);
    }
}
class TCELETargetInfo : TCETargetInfo {
    this() { }
    this(Triple T) {
        super(T);
        this.resetDataLayout("e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:32-v128:32:32-v256:32:32-v512:32:32-v1024:32:32-a0:0:32-n32"d);
    }
}
class VETargetInfo : TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
        this.resetDataLayout("e-m:e-i64:64-n32:64-S128-v64:64:64-v128:64:64-v256:64:64-v512:64:64-v1024:64:64-v2048:64:64-v4096:64:64-v8192:64:64-v16384:64:64"d);
    }
}
class WebAssemblyTargetInfo : TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class WebAssembly32TargetInfo : WebAssemblyTargetInfo {
    this() { }
    this(Triple T) {
        super(T);
        this.resetDataLayout("e-m:e-p:32:32-i64:64-n32:64-S128-ni:1"d);
    }
}
class WebAssembly64TargetInfo : WebAssemblyTargetInfo {
    this() { }
    this(Triple T) {
        super(T);
        this.resetDataLayout("e-m:e-p:64:64-i64:64-n32:64-S128-ni:1"d);
    }
}
class X86TargetInfo : TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class X86_32TargetInfo : X86TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
        if (isOSBinFormatMachO(T)) {
            this.resetDataLayout("e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:32-n8:16:32-S128"d, "_"d);
        }
        else {
            this.resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:32-n8:16:32-S128"d);
        }
    }
}
class DarwinI386TargetInfo : DarwinTargetInfo!(X86_32TargetInfo) {
    this() { }
    this(Triple T) {
        super(T);
        this.resetDataLayout("e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:128-n8:16:32-S128"d, "_"d);
    }
}
class WindowsX86_32TargetInfo : WindowsTargetInfo!(X86_32TargetInfo) {
    this() { }
    this(Triple T) {
        super(T);
        bool IsWinCOFF = isOSWindows(T) && isOSBinFormatCOFF(T);
        if (IsWinCOFF) {
            this.resetDataLayout("e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:32-n8:16:32-a:0:32-S32"d, "_"d);
        }
        else {
            this.resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:32-n8:16:32-a:0:32-S32"d);
        }
    }
}
class MicrosoftX86_32TargetInfo : WindowsX86_32TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class MinGWX86_32TargetInfo : WindowsX86_32TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class CygwinX86_32TargetInfo : X86_32TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
        this.resetDataLayout("e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:32-n8:16:32-a:0:32-S32"d, "_"d);
    }
}
class HaikuX86_32TargetInfo : HaikuTargetInfo!(X86_32TargetInfo) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class MCUX86_32TargetInfo : X86_32TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
        this.resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:32-f64:32-f128:32-n8:16:32-a:0:32-S32"d);
    }
}
class RTEMSX86_32TargetInfo : X86_32TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class NetBSDI386TargetInfo : NetBSDTargetInfo!(X86_32TargetInfo) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class OpenBSDI386TargetInfo : OpenBSDTargetInfo!(X86_32TargetInfo) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class X86_64TargetInfo : X86TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
        bool IsX32 = isX32(T);
        bool IsWinCOFF = isOSWindows(T) && isOSBinFormatCOFF(T);
        if (IsX32) {
            this.resetDataLayout("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"d);
        }
        else if (IsWinCOFF) {
            this.resetDataLayout("e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"d);
        }
        else {
            this.resetDataLayout("e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"d);
        }
    }
}
class WindowsX86_64TargetInfo : WindowsTargetInfo!(X86_64TargetInfo) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class MicrosoftX86_64TargetInfo : WindowsX86_64TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class MinGWX86_64TargetInfo : WindowsX86_64TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class CygwinX86_64TargetInfo : X86_64TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class DarwinX86_64TargetInfo : DarwinTargetInfo!(X86_64TargetInfo) {
    this() { }
    this(Triple T) {
        super(T);
        this.resetDataLayout("e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"d, "_"d);
    }
}
class OpenBSDX86_64TargetInfo : OpenBSDTargetInfo!(X86_64TargetInfo) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class AndroidX86_32TargetInfo : LinuxTargetInfo!(X86_32TargetInfo) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class AndroidX86_64TargetInfo : LinuxTargetInfo!(X86_64TargetInfo) {
    this() { }
    this(Triple T) {
        super(T);
    }
}
class XCoreTargetInfo : TargetInfo {
    this() { }
    this(Triple T) {
        super(T);
        this.resetDataLayout("e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:32-f64:32-a:0:32-n32"d);
    }
}
TargetInfo AllocateTarget(Triple T) {
    OSType os = T.getOSType();
    switch (T.Arch) {
        case ArchType.arc: {
            return new ARCTargetInfo(T);
        }
        case ArchType.xcore: {
            return new XCoreTargetInfo(T);
        }
        case ArchType.hexagon: {
            if (os == OSType.Linux && getEnvironment(T) == EnvironmentType.Musl) {
                return new LinuxTargetInfo!(HexagonTargetInfo)(T);
            }
            return new HexagonTargetInfo(T);
        }
        case ArchType.lanai: {
            return new LanaiTargetInfo(T);
        }
        case ArchType.aarch64_32: {
            if (isOSDarwin(T)) {
                return new DarwinAArch64TargetInfo(T);
            }
            return ··null!(TargetInfo);
        }
        case ArchType.aarch64: {
            if (isOSDarwin(T)) {
                return new DarwinAArch64TargetInfo(T);
            }
            switch (os) {
                case OSType.CloudABI: {
                    return new CloudABITargetInfo!(AArch64leTargetInfo)(T);
                }
                case OSType.FreeBSD: {
                    return new FreeBSDTargetInfo!(AArch64leTargetInfo)(T);
                }
                case OSType.Fuchsia: {
                    return new FuchsiaTargetInfo!(AArch64leTargetInfo)(T);
                }
                case OSType.Linux: {
                    return new LinuxTargetInfo!(AArch64leTargetInfo)(T);
                }
                case OSType.NetBSD: {
                    return new NetBSDTargetInfo!(AArch64leTargetInfo)(T);
                }
                case OSType.OpenBSD: {
                    return new OpenBSDTargetInfo!(AArch64leTargetInfo)(T);
                }
                case OSType.Win32: {
                    switch (getEnvironment(T)) {
                        case EnvironmentType.GNU: {
                            return new MinGWARM64TargetInfo(T);
                        }
                        case EnvironmentType.MSVC:
                        default: {
                            return new MicrosoftARM64TargetInfo(T);
                        }
                    }
                }
                default: {
                    return new AArch64leTargetInfo(T);
                }
            }
        }
        case ArchType.aarch64_be: {
            switch (os) {
                case OSType.FreeBSD: {
                    return new FreeBSDTargetInfo!(AArch64beTargetInfo)(T);
                }
                case OSType.Fuchsia: {
                    return new FuchsiaTargetInfo!(AArch64beTargetInfo)(T);
                }
                case OSType.Linux: {
                    return new LinuxTargetInfo!(AArch64beTargetInfo)(T);
                }
                case OSType.NetBSD: {
                    return new NetBSDTargetInfo!(AArch64beTargetInfo)(T);
                }
                default: {
                    return new AArch64beTargetInfo(T);
                }
            }
        }
        case ArchType.arm:
        case ArchType.thumb: {
            if (isOSBinFormatMachO(T)) {
                return new DarwinARMTargetInfo(T);
            }
            switch (os) {
                case OSType.CloudABI: {
                    return new CloudABITargetInfo!(ARMleTargetInfo)(T);
                }
                case OSType.Linux: {
                    return new LinuxTargetInfo!(ARMleTargetInfo)(T);
                }
                case OSType.FreeBSD: {
                    return new FreeBSDTargetInfo!(ARMleTargetInfo)(T);
                }
                case OSType.NetBSD: {
                    return new NetBSDTargetInfo!(ARMleTargetInfo)(T);
                }
                case OSType.OpenBSD: {
                    return new OpenBSDTargetInfo!(ARMleTargetInfo)(T);
                }
                case OSType.RTEMS: {
                    return new RTEMSTargetInfo!(ARMleTargetInfo)(T);
                }
                case OSType.NaCl: {
                    return new NaClTargetInfo!(ARMleTargetInfo)(T);
                }
                case OSType.Win32: {
                    switch (getEnvironment(T)) {
                        case EnvironmentType.Cygnus: {
                            return new CygwinARMTargetInfo(T);
                        }
                        case EnvironmentType.GNU: {
                            return new MinGWARMTargetInfo(T);
                        }
                        case EnvironmentType.Itanium: {
                            return new ItaniumWindowsARMleTargetInfo(T);
                        }
                        case EnvironmentType.MSVC:
                        default: {
                            return new MicrosoftARMleTargetInfo(T);
                        }
                    }
                }
                default: {
                    return new ARMleTargetInfo(T);
                }
            }
        }
        case ArchType.armeb:
        case ArchType.thumbeb: {
            if (isOSDarwin(T)) {
                return new DarwinARMTargetInfo(T);
            }
            switch (os) {
                case OSType.Linux: {
                    return new LinuxTargetInfo!(ARMbeTargetInfo)(T);
                }
                case OSType.FreeBSD: {
                    return new FreeBSDTargetInfo!(ARMbeTargetInfo)(T);
                }
                case OSType.NetBSD: {
                    return new NetBSDTargetInfo!(ARMbeTargetInfo)(T);
                }
                case OSType.OpenBSD: {
                    return new OpenBSDTargetInfo!(ARMbeTargetInfo)(T);
                }
                case OSType.RTEMS: {
                    return new RTEMSTargetInfo!(ARMbeTargetInfo)(T);
                }
                case OSType.NaCl: {
                    return new NaClTargetInfo!(ARMbeTargetInfo)(T);
                }
                default: {
                    return new ARMbeTargetInfo(T);
                }
            }
        }
        case ArchType.avr: {
            return new AVRTargetInfo(T);
        }
        case ArchType.bpfeb:
        case ArchType.bpfel: {
            return new BPFTargetInfo(T);
        }
        case ArchType.msp430: {
            return new MSP430TargetInfo(T);
        }
        case ArchType.mips: {
            switch (os) {
                case OSType.Linux: {
                    return new LinuxTargetInfo!(MipsTargetInfo)(T);
                }
                case OSType.RTEMS: {
                    return new RTEMSTargetInfo!(MipsTargetInfo)(T);
                }
                case OSType.FreeBSD: {
                    return new FreeBSDTargetInfo!(MipsTargetInfo)(T);
                }
                case OSType.NetBSD: {
                    return new NetBSDTargetInfo!(MipsTargetInfo)(T);
                }
                default: {
                    return new MipsTargetInfo(T);
                }
            }
        }
        case ArchType.mipsel: {
            switch (os) {
                case OSType.Linux: {
                    return new LinuxTargetInfo!(MipsTargetInfo)(T);
                }
                case OSType.RTEMS: {
                    return new RTEMSTargetInfo!(MipsTargetInfo)(T);
                }
                case OSType.FreeBSD: {
                    return new FreeBSDTargetInfo!(MipsTargetInfo)(T);
                }
                case OSType.NetBSD: {
                    return new NetBSDTargetInfo!(MipsTargetInfo)(T);
                }
                case OSType.NaCl: {
                    return new NaClTargetInfo!(NaClMips32TargetInfo)(T);
                }
                default: {
                    return new MipsTargetInfo(T);
                }
            }
        }
        case ArchType.mips64: {
            switch (os) {
                case OSType.Linux: {
                    return new LinuxTargetInfo!(MipsTargetInfo)(T);
                }
                case OSType.RTEMS: {
                    return new RTEMSTargetInfo!(MipsTargetInfo)(T);
                }
                case OSType.FreeBSD: {
                    return new FreeBSDTargetInfo!(MipsTargetInfo)(T);
                }
                case OSType.NetBSD: {
                    return new NetBSDTargetInfo!(MipsTargetInfo)(T);
                }
                case OSType.OpenBSD: {
                    return new OpenBSDTargetInfo!(MipsTargetInfo)(T);
                }
                default: {
                    return new MipsTargetInfo(T);
                }
            }
        }
        case ArchType.mips64el: {
            switch (os) {
                case OSType.Linux: {
                    return new LinuxTargetInfo!(MipsTargetInfo)(T);
                }
                case OSType.RTEMS: {
                    return new RTEMSTargetInfo!(MipsTargetInfo)(T);
                }
                case OSType.FreeBSD: {
                    return new FreeBSDTargetInfo!(MipsTargetInfo)(T);
                }
                case OSType.NetBSD: {
                    return new NetBSDTargetInfo!(MipsTargetInfo)(T);
                }
                case OSType.OpenBSD: {
                    return new OpenBSDTargetInfo!(MipsTargetInfo)(T);
                }
                default: {
                    return new MipsTargetInfo(T);
                }
            }
        }
        case ArchType.m68k: {
            switch (os) {
                case OSType.Linux: {
                    return new LinuxTargetInfo!(M68kTargetInfo)(T);
                }
                case OSType.NetBSD: {
                    return new NetBSDTargetInfo!(M68kTargetInfo)(T);
                }
                default: {
                    return new M68kTargetInfo(T);
                }
            }
        }
        case ArchType.le32: {
            switch (os) {
                case OSType.NaCl: {
                    return new NaClTargetInfo!(PNaClTargetInfo)(T);
                }
                default: {
                    return ··null!(TargetInfo);
                }
            }
        }
        case ArchType.le64: {
            return new Le64TargetInfo(T);
        }
        case ArchType.ppc: {
            if (isOSDarwin(T)) {
                return new DarwinPPC32TargetInfo(T);
            }
            switch (os) {
                case OSType.Linux: {
                    return new LinuxTargetInfo!(PPC32TargetInfo)(T);
                }
                case OSType.FreeBSD: {
                    return new FreeBSDTargetInfo!(PPC32TargetInfo)(T);
                }
                case OSType.NetBSD: {
                    return new NetBSDTargetInfo!(PPC32TargetInfo)(T);
                }
                case OSType.OpenBSD: {
                    return new OpenBSDTargetInfo!(PPC32TargetInfo)(T);
                }
                case OSType.RTEMS: {
                    return new RTEMSTargetInfo!(PPC32TargetInfo)(T);
                }
                case OSType.AIX: {
                    return new AIXPPC32TargetInfo(T);
                }
                default: {
                    return new PPC32TargetInfo(T);
                }
            }
        }
        case ArchType.ppcle: {
            switch (os) {
                case OSType.Linux: {
                    return new LinuxTargetInfo!(PPC32TargetInfo)(T);
                }
                case OSType.FreeBSD: {
                    return new FreeBSDTargetInfo!(PPC32TargetInfo)(T);
                }
                default: {
                    return new PPC32TargetInfo(T);
                }
            }
        }
        case ArchType.ppc64: {
            if (isOSDarwin(T)) {
                return new DarwinPPC64TargetInfo(T);
            }
            switch (os) {
                case OSType.Linux: {
                    return new LinuxTargetInfo!(PPC64TargetInfo)(T);
                }
                case OSType.Lv2: {
                    return new PS3PPUTargetInfo!(PPC64TargetInfo)(T);
                }
                case OSType.FreeBSD: {
                    return new FreeBSDTargetInfo!(PPC64TargetInfo)(T);
                }
                case OSType.NetBSD: {
                    return new NetBSDTargetInfo!(PPC64TargetInfo)(T);
                }
                case OSType.OpenBSD: {
                    return new OpenBSDTargetInfo!(PPC64TargetInfo)(T);
                }
                case OSType.AIX: {
                    return new AIXPPC64TargetInfo(T);
                }
                default: {
                    return new PPC64TargetInfo(T);
                }
            }
        }
        case ArchType.ppc64le: {
            switch (os) {
                case OSType.Linux: {
                    return new LinuxTargetInfo!(PPC64TargetInfo)(T);
                }
                case OSType.FreeBSD: {
                    return new FreeBSDTargetInfo!(PPC64TargetInfo)(T);
                }
                case OSType.NetBSD: {
                    return new NetBSDTargetInfo!(PPC64TargetInfo)(T);
                }
                case OSType.OpenBSD: {
                    return new OpenBSDTargetInfo!(PPC64TargetInfo)(T);
                }
                default: {
                    return new PPC64TargetInfo(T);
                }
            }
        }
        case ArchType.nvptx: {
            return new NVPTXTargetInfo(T, /*TargetPointerWidth=*/ 32);
        }
        case ArchType.nvptx64: {
            return new NVPTXTargetInfo(T, /*TargetPointerWidth=*/ 64);
        }
        case ArchType.amdgcn:
        case ArchType.r600: {
            return new AMDGPUTargetInfo(T);
        }
        case ArchType.riscv32: {
            // TODO: add cases for NetBSD, RTEMS once tested.
            switch (os) {
                case OSType.FreeBSD: {
                    return new FreeBSDTargetInfo!(RISCV32TargetInfo)(T);
                }
                case OSType.Linux: {
                    return new LinuxTargetInfo!(RISCV32TargetInfo)(T);
                }
                default: {
                    return new RISCV32TargetInfo(T);
                }
            }
        }
        case ArchType.riscv64: {
            // TODO: add cases for NetBSD, RTEMS once tested.
            switch (os) {
                case OSType.FreeBSD: {
                    return new FreeBSDTargetInfo!(RISCV64TargetInfo)(T);
                }
                case OSType.OpenBSD: {
                    return new OpenBSDTargetInfo!(RISCV64TargetInfo)(T);
                }
                case OSType.Fuchsia: {
                    return new FuchsiaTargetInfo!(RISCV64TargetInfo)(T);
                }
                case OSType.Linux: {
                    return new LinuxTargetInfo!(RISCV64TargetInfo)(T);
                }
                default: {
                    return new RISCV64TargetInfo(T);
                }
            }
        }
        case ArchType.sparc: {
            switch (os) {
                case OSType.Linux: {
                    return new LinuxTargetInfo!(SparcV8TargetInfo)(T);
                }
                case OSType.Solaris: {
                    return new SolarisTargetInfo!(SparcV8TargetInfo)(T);
                }
                case OSType.NetBSD: {
                    return new NetBSDTargetInfo!(SparcV8TargetInfo)(T);
                }
                case OSType.RTEMS: {
                    return new RTEMSTargetInfo!(SparcV8TargetInfo)(T);
                }
                default: {
                    return new SparcV8TargetInfo(T);
                }
            }
        }
        // The 'sparcel' architecture copies all the above cases except for Solaris.
        case ArchType.sparcel: {
            switch (os) {
                case OSType.Linux: {
                    return new LinuxTargetInfo!(SparcV8elTargetInfo)(T);
                }
                case OSType.NetBSD: {
                    return new NetBSDTargetInfo!(SparcV8elTargetInfo)(T);
                }
                case OSType.RTEMS: {
                    return new RTEMSTargetInfo!(SparcV8elTargetInfo)(T);
                }
                default: {
                    return new SparcV8elTargetInfo(T);
                }
            }
        }
        case ArchType.sparcv9: {
            switch (os) {
                case OSType.Linux: {
                    return new LinuxTargetInfo!(SparcV9TargetInfo)(T);
                }
                case OSType.Solaris: {
                    return new SolarisTargetInfo!(SparcV9TargetInfo)(T);
                }
                case OSType.NetBSD: {
                    return new NetBSDTargetInfo!(SparcV9TargetInfo)(T);
                }
                case OSType.OpenBSD: {
                    return new OpenBSDTargetInfo!(SparcV9TargetInfo)(T);
                }
                case OSType.FreeBSD: {
                    return new FreeBSDTargetInfo!(SparcV9TargetInfo)(T);
                }
                default: {
                    return new SparcV9TargetInfo(T);
                }
            }
        }
        case ArchType.systemz: {
            switch (os) {
                case OSType.Linux: {
                    return new LinuxTargetInfo!(SystemZTargetInfo)(T);
                }
                case OSType.ZOS: {
                    return new ZOSTargetInfo!(SystemZTargetInfo)(T);
                }
                default: {
                    return new SystemZTargetInfo(T);
                }
            }
        }
        case ArchType.tce: {
            return new TCETargetInfo(T);
        }
        case ArchType.tcele: {
            return new TCELETargetInfo(T);
        }
        case ArchType.x86: {
            if (isOSDarwin(T)) {
                return new DarwinI386TargetInfo(T);
            }
            switch (os) {
                case OSType.Ananas: {
                    return new AnanasTargetInfo!(X86_32TargetInfo)(T);
                }
                case OSType.CloudABI: {
                    return new CloudABITargetInfo!(X86_32TargetInfo)(T);
                }
                case OSType.Linux: {
                    switch (getEnvironment(T)) {
                        case EnvironmentType.Android: {
                            return new AndroidX86_32TargetInfo(T);
                        }
                        default: {
                            return new LinuxTargetInfo!(X86_32TargetInfo)(T);
                        }
                    }
                }
                case OSType.DragonFly: {
                    return new DragonFlyBSDTargetInfo!(X86_32TargetInfo)(T);
                }
                case OSType.NetBSD: {
                    return new NetBSDI386TargetInfo(T);
                }
                case OSType.OpenBSD: {
                    return new OpenBSDI386TargetInfo(T);
                }
                case OSType.FreeBSD: {
                    return new FreeBSDTargetInfo!(X86_32TargetInfo)(T);
                }
                case OSType.Fuchsia: {
                    return new FuchsiaTargetInfo!(X86_32TargetInfo)(T);
                }
                case OSType.KFreeBSD: {
                    return new KFreeBSDTargetInfo!(X86_32TargetInfo)(T);
                }
                case OSType.Minix: {
                    return new MinixTargetInfo!(X86_32TargetInfo)(T);
                }
                case OSType.Solaris: {
                    return new SolarisTargetInfo!(X86_32TargetInfo)(T);
                }
                case OSType.Win32: {
                    switch (getEnvironment(T)) {
                        case EnvironmentType.Cygnus: {
                            return new CygwinX86_32TargetInfo(T);
                        }
                        case EnvironmentType.GNU: {
                            return new MinGWX86_32TargetInfo(T);
                        }
                        case EnvironmentType.Itanium:
                        case EnvironmentType.MSVC:
                        default: {
                            return new MicrosoftX86_32TargetInfo(T);
                        }
                    }
                }
                case OSType.Haiku: {
                    return new HaikuX86_32TargetInfo(T);
                }
                case OSType.RTEMS: {
                    return new RTEMSX86_32TargetInfo(T);
                }
                case OSType.NaCl: {
                    return new NaClTargetInfo!(X86_32TargetInfo)(T);
                }
                case OSType.ELFIAMCU: {
                    return new MCUX86_32TargetInfo(T);
                }
                case OSType.Hurd: {
                    return new HurdTargetInfo!(X86_32TargetInfo)(T);
                }
                default: {
                    return new X86_32TargetInfo(T);
                }
            }
        }
        case ArchType.x86_64: {
            if (isOSDarwin(T) || isOSBinFormatMachO(T)) {
                return new DarwinX86_64TargetInfo(T);
            }
            switch (os) {
                case OSType.Ananas: {
                    return new AnanasTargetInfo!(X86_64TargetInfo)(T);
                }
                case OSType.CloudABI: {
                    return new CloudABITargetInfo!(X86_64TargetInfo)(T);
                }
                case OSType.Linux: {
                    switch (getEnvironment(T)) {
                        case EnvironmentType.Android: {
                            return new AndroidX86_64TargetInfo(T);
                        }
                        default: {
                            return new LinuxTargetInfo!(X86_64TargetInfo)(T);
                        }
                    }
                }
                case OSType.DragonFly: {
                    return new DragonFlyBSDTargetInfo!(X86_64TargetInfo)(T);
                }
                case OSType.NetBSD: {
                    return new NetBSDTargetInfo!(X86_64TargetInfo)(T);
                }
                case OSType.OpenBSD: {
                    return new OpenBSDX86_64TargetInfo(T);
                }
                case OSType.FreeBSD: {
                    return new FreeBSDTargetInfo!(X86_64TargetInfo)(T);
                }
                case OSType.Fuchsia: {
                    return new FuchsiaTargetInfo!(X86_64TargetInfo)(T);
                }
                case OSType.KFreeBSD: {
                    return new KFreeBSDTargetInfo!(X86_64TargetInfo)(T);
                }
                case OSType.Solaris: {
                    return new SolarisTargetInfo!(X86_64TargetInfo)(T);
                }
                case OSType.Win32: {
                    switch (getEnvironment(T)) {
                        case EnvironmentType.Cygnus: {
                            return new CygwinX86_64TargetInfo(T);
                        }
                        case EnvironmentType.GNU: {
                            return new MinGWX86_64TargetInfo(T);
                        }
                        case EnvironmentType.MSVC:
                        default: {
                            return new MicrosoftX86_64TargetInfo(T);
                        }
                    }
                }
                case OSType.Haiku: {
                    return new HaikuTargetInfo!(X86_64TargetInfo)(T);
                }
                case OSType.NaCl: {
                    return new NaClTargetInfo!(X86_64TargetInfo)(T);
                }
                case OSType.PS4: {
                    return new PS4OSTargetInfo!(X86_64TargetInfo)(T);
                }
                default: {
                    return new X86_64TargetInfo(T);
                }
            }
        }
        case ArchType.spir: {
            if (os != OSType.UnknownOS || getEnvironment(T) != EnvironmentType.UnknownEnvironment) {
                return ··null!(TargetInfo);
            }
            return new SPIR32TargetInfo(T);
        }
        case ArchType.spir64: {
            if (os != OSType.UnknownOS || getEnvironment(T) != EnvironmentType.UnknownEnvironment) {
                return ··null!(TargetInfo);
            }
            return new SPIR64TargetInfo(T);
        }
        case ArchType.wasm32: {
            if (T.getSubArch() != SubArchType.NoSubArch || T.getVendor() != VendorType.UnknownVendor || !isOSBinFormatWasm(T)) {
                return ··null!(TargetInfo);
            }
            switch (os) {
                case OSType.WASI: {
                    return new WASITargetInfo!(WebAssembly32TargetInfo)(T);
                }
                case OSType.Emscripten: {
                    return new EmscriptenTargetInfo!(WebAssembly32TargetInfo)(T);
                }
                case OSType.UnknownOS: {
                    return new WebAssemblyOSTargetInfo!(WebAssembly32TargetInfo)(T);
                }
                default: {
                    return ··null!(TargetInfo);
                }
            }
        }
        case ArchType.wasm64: {
            if (T.getSubArch() != SubArchType.NoSubArch || T.getVendor() != VendorType.UnknownVendor || !isOSBinFormatWasm(T)) {
                return ··null!(TargetInfo);
            }
            switch (os) {
                case OSType.WASI: {
                    return new WASITargetInfo!(WebAssembly64TargetInfo)(T);
                }
                case OSType.Emscripten: {
                    return new EmscriptenTargetInfo!(WebAssembly64TargetInfo)(T);
                }
                case OSType.UnknownOS: {
                    return new WebAssemblyOSTargetInfo!(WebAssembly64TargetInfo)(T);
                }
                default: {
                    return ··null!(TargetInfo);
                }
            }
        }
        case ArchType.renderscript32: {
            return new LinuxTargetInfo!(RenderScript32TargetInfo)(T);
        }
        case ArchType.renderscript64: {
            return new LinuxTargetInfo!(RenderScript64TargetInfo)(T);
        }
        case ArchType.ve: {
            return new LinuxTargetInfo!(VETargetInfo)(T);
        }
        default: break;
    }
    return ··null!(TargetInfo);
}
